home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / doc / sushi.doc < prev    next >
Text File  |  1994-02-13  |  14KB  |  423 lines

  1. sushi v37.10
  2. (c) Copyright 1992-93 Commodore-Amiga, Inc.  All Rights Reserved
  3.  
  4. Sushi - intercepts raw serial debugging output on your own machine. Opts:
  5.  
  6. startup: [ON] [BUFK=n (pow 2 only)] [NOPROMPT] [QUIET] [ASKEXIT] [ASKSAVE]
  7.  
  8. runtime: [OFF] [SAVE] [SAVEAS filename] [EMPTY]
  9.  
  10. by Carolyn Scheppner - CATS
  11.  
  12.  
  13. Thanks to Steve Tibbett and Christian E. Hopps for their own
  14. implementations, "Reporter" and "Detective", which made me insatiably
  15. curious and drove me to write my own.
  16.  
  17. Sushi is a tool to intercept the raw serial output of Enforcer 2.8b,
  18. Enforcer.megastack 26.f, Mungwall, and all tool and application debugging
  19. output that uses kprintf.  This makes it possible to use serial debugging
  20. on a single Amiga, without interfering with attached serial hardware
  21. such as modems and serial printers.  Sushi also provides optional
  22. signalling and buffer access to an external display/watcher program.
  23. Sushi 37.9 should fix command line redirection of sushi output to a file.
  24. Sushi 37.10 fixes the EMPTY keyword which tells another running Sushi
  25. to empty (i.e. not save) its buffer.
  26.  
  27. QUICK USAGE
  28. ===========
  29. Here's what's in my user-startup:
  30.  
  31. run >NIL: mungwall NAMETAG
  32. ; NOTE - with older Enforcer 2.8b, instead use: enforcer >NIL:
  33. run >NIL: enforcer RAWIO
  34. newsushi
  35.  
  36. where "newsushi" is an s: script file (with "s" bit set) containing:
  37.  
  38. --------------- cut here --------------
  39. .key none
  40. .bra {
  41. .ket }
  42. run >NIL: sushi <>"CON:0/20/640/100/Sushi  CTRL-E=Empty  CTRL-F=File/AUTO/CLOSE/WAIT/INACTIVE" ON BUFK=64 NOPROMPT ASKEXIT ASKSAVE
  43. --------------- cut here --------------
  44.  
  45. Note the INACTIVE keyword in the CON: string which tells the CON to open
  46. INACTIVE (thereby not changing your active window if it pops ups).
  47.  
  48. WARNING - some third-party CON: replacements do not handle the in/out <>
  49. redirection shown above.  If you are using a third-party CON, you may need
  50. to change to just out redirection (>) and remove the ASKSAVE and ASKEXIT
  51. options since your Sushi window will not have input.
  52.  
  53.  
  54. If Sushi can find Enforcer 2.8b, or 2.6f megastack resident, then it
  55. can patch these Enforcers to redirect their output.  Other debugging
  56. output is intercepted by patching low level debugging output functions.
  57. Newer versions of Enforcer (37.x) have a RAWIO option which allows Sushi
  58. to capture their output.  Warning - if you are using the older Enforcer
  59. 2.8b or 2.6f, and you need to turn off Enforcer, first remove Sushi.
  60.  
  61. All standard serial debugging functions are intercepted.  Currently,
  62. the patch to the serial debugging input function just returns a 'y'.
  63. Standard serial debugging output and Enforcer output go into sushi's
  64. circular buffer (user-definable size, default 32K), where it is noticed
  65. by the Sushi process and written to stdout.  The Sushi process is signalled
  66. whenever a carriage return or linefeed comes through kprintf.
  67.  
  68. if Enforcer 2.8b or 2.6f has been found and patched, Sushi will also
  69. wake up every 1/10 second to check for output in its buffer (since it
  70. is not safe for Sushi's Enforcer wedge to signal Sushi's process during
  71. an Enforcer bus error).  If you are not using Enforcer 2.8b or 2.6f but
  72. you still want Sushi to wake up every 1/10 second to check for output
  73. (instead of only waking up on carriage returns and linefeeds), then pass
  74. the special hidden command line option "TimerOn" when you start up Sushi.
  75.  
  76. Sushi's standard output can be redirected elsewhere (for example, to
  77. a multiserial handler or an AUTO/WAIT/CLOSE CON window).  Or Sushi can
  78. be run in QUIET mode and external watcher/display tool can be signalled
  79. by Sushi for more elaborate display of the output.  (i.e. If you personally
  80. want your machine to MOO when you get a mungwall hit, and flash purple
  81. polka dots for Enforcer hits, you can write an external sushi watcher
  82. or display tool to do that).
  83.  
  84.  
  85. Sushi has several startup options, and several runtime options:
  86.  
  87. startup: [ON] [BUFK=n (pow 2 only)] [NOPROMPT] [QUIET] [ASKEXIT] [ASKSAVE]
  88.  
  89. runtime: [OFF] [SAVE] [SAVEAS filename] [EMPTY]
  90.  
  91.  
  92. Startup Options
  93. ===============
  94. ON        Default (not required)
  95.  
  96. BUFK=n        Changes circular buffer size from default 32K to specified
  97.         power-of-2 K from 4K to 2028K.  Sushi will always round
  98.         the specified size down to a power of two K (32K, 64K, etc).
  99.  
  100. NOPROMPT    Turns off the "sushi installed" and "enforcer not found"
  101.         prompts.  Useful if redirecting sushi to an AUTO CON
  102.         window in your user-startup.
  103.  
  104. QUIET        Causes Sushi to just buffer all debugging output.
  105.         Effectively silences serial debugging output.
  106.         Useful in conjunction with an external sushi watcher
  107.         or displayer (see later explanation).
  108.  
  109. ASKSAVE        Cause Sushi to ask you if you want to save the buffer
  110.         when you exit Sushi.  If there's nothing in the buffer,
  111.         it won't ask.  Make SURE sushi has a stdin if you
  112.         use this option.  If sushi thinks it has no stdin,
  113.         it will save to t:sushi.out.  This option should only
  114.         be used if Sushi has an input stream - i.e. if Sushi
  115.         is not RUN/redirected, or if Sushi has in/out redirection
  116.         in a CON: window.
  117.  
  118. ASKEXIT        Cause Sushi to ask you if you REALLY want to exit if
  119.         a CTRL-C is received.  This is good for people like
  120.         me who might accidentally CTRL-C in a Sushi window when
  121.         they meant to do it somewhere else.   This option should
  122.         only be used if Sushi has an input stream - i.e. if Sushi
  123.         is not RUN/redirected, or if Sushi has in/out redirection
  124.         in a CON: window.
  125.  
  126. TIMERON        Cause Sushi to wake up every 1/10 second to check for
  127.         output even if Enforcer 2.8b or 2.6f have not been patched.
  128.         Without this option, Sushi will just wake up every time a
  129.         carriage return or linefeed is output.
  130.  
  131.  
  132. Runtime Options
  133. ===============
  134. OFF        Signals active running copy of Sushi to exit (CTRL_C)
  135.  
  136. EMPTY        Signals active running copy of Sushi to empty its buffer.
  137.  
  138. SAVE        Finds active running copy of Sushi and saves its buffer
  139.         as t:sushi.out
  140.  
  141. SAVEAS name    Finds active running copy of Sushi and saves its buffer
  142.         as specified filename
  143.  
  144.  
  145.  
  146.  
  147. Example Startup Usage
  148. =====================
  149.  
  150. sushi ASKSAVE    (in its own shell window)
  151.  
  152. run >NIL: sushi  >"CON:0/20/640/120/Sushi/AUTO/CLOSE/WAIT/INACTIVE" ON NOPROMPT
  153.  
  154. run >NIL: sushi <>"CON:0/20/640/120/Sushi/AUTO/CLOSE/WAIT/INACTIVE" ON NOPROMPT
  155.  
  156.    NOTE !!!  The double redirection as above (<>) works with Amiga CON:
  157.    V37 or higher.  It may not work with some third-party CON's.
  158.    The ASKSAVE and ASKEXIT options require input from a CON window.
  159.  
  160. run sushi >ram:hits (all output redirected to a file)
  161.  
  162. run sushi NOPROMPT QUIET    (for use with external displayer)
  163.  
  164. NOTE: You may want use the following title for a sushi AUTO CON window:
  165.     /Sushi   CTRL-E:Empty   CTRL-F:File/
  166.  
  167.  
  168. Keyboard and BREAK signals
  169. ==========================
  170. CTRL-C: To quit Sushi, CTRL-C it (if it has its own window), send it
  171.     a CTRL-C with the c:BREAK command, or run sushi a second time
  172.     with the OFF keyword.
  173.  
  174. CTRL-E: Tells Sushi to empty (clear) its buffer.
  175.  
  176. CTRL-F: Tells Sushi to save its own buffer to file t:sushi.out
  177.  
  178.  
  179. Other Runtime Usage
  180. ===================
  181. sushi OFF            ; tell active running Sushi to try to exit
  182. sushi SAVE            ; save buffer of active Sushi
  183. sushi SAVEAS ram:myhits EMPTY   ; save buffer as ram:myhits and clear buffer
  184.  
  185. Usually, I just CTRL-F in the Sushi window, and it saves its buffer as
  186. t:sushi.out.
  187.  
  188.  
  189. Programmer Interface
  190. ====================
  191.  
  192. Sushi allows a external tasks to find and read its buffer, and allows
  193. one external task to register itself to be signalled by Sushi
  194. whenever there is new information in the buffer.  Sushi will refuse
  195. to exit as long as a task is registered with it.  So make sure
  196. you remove your pointer from Sushi's port before you exit !!!!
  197.  
  198. Here is an example that finds Sushi and installs itself as the
  199. external sigtask.  Sushi will signal this task whenever there
  200. is new information in sushi's buffer.
  201.  
  202. The example also shows (ifdef'd out)  how to ask Sushi to
  203. write its buffer, flush its buffer, or exit.
  204.  
  205.  
  206.  
  207. ;/* ext_sushi.c - Execute me to compile me with SAS C 5.10
  208. LC -b1 -cfistq -v -y -j73 ext_sushi.c
  209. Blink FROM LIB:c.o,ext_sushi.o TO ext_sushi LIBRARY LIB:LC.lib,LIB:Amiga.lib
  210. quit
  211.  
  212. ext_sushi.c - An example of an external display or watcher program
  213.         which is signalled by sushi.
  214. */
  215.  
  216. #include <exec/types.h>
  217. #include <exec/memory.h>
  218. #include <libraries/dos.h>
  219.  
  220. #include <clib/exec_protos.h>
  221. #include <clib/dos_protos.h>
  222. #include <stdlib.h>
  223. #include <stdio.h>
  224. #include <string.h>
  225.  
  226. #ifdef LATTICE
  227. int CXBRK(void)  { return(0); }  /* Disable Lattice CTRL/C handling */
  228. void chkabort(void) { return; }  /* really */
  229.  
  230. extern struct Library *SysBase;
  231. extern struct Library *DOSBase;
  232. #include "pragmas/exec_pragmas.h"
  233. #include "pragmas/dos_pragmas.h"
  234. #endif
  235.  
  236.  
  237. #define MINARGS 1
  238.  
  239. UBYTE *vers = "\0$VER: ext_sushi 37.2";
  240. UBYTE *Copyright = 
  241.   "ext_sushi v37.2\nCopyright (c) 1992 Commodore-Amiga, Inc.  All Rights Reserved";
  242. UBYTE *usage = "Usage: ext_sushi";
  243.  
  244.  
  245. void bye(UBYTE *s, int e);
  246. void cleanup(void);
  247.  
  248.  
  249. UBYTE sushiname[] = "sushi_CAS_port";
  250.  
  251. /* Definitions of WTP and AppStruct structures */
  252.  
  253. struct AppStruct {
  254.    /* These are for READ-ONLY use by external application */
  255.    UBYTE    *subuf;        /* Sushi's circular output buffer */
  256.    ULONG    subufsize;    /* Size of buffer in bytes (a power of 2K) */
  257.    ULONG    subufi;        /* Where Sushi will place next char received */
  258.    ULONG    subufli;    /* Sushi's local index of what it has processed */
  259.    ULONG    wrapcnt;    /* How may times circular buffer has wrapped */ 
  260.    ULONG    wrapmask;    /* Hex mask Sushi uses when wrapping subufi */
  261.  
  262.    /* External app writes to these if not in use; must clear them before exiting */
  263.    struct Task    *extsigtask;
  264.    LONG        extsignum;
  265.    ULONG    extsignal;
  266.  
  267.    /* Microseconds that Sushi waits between checking for Enforcer hits.
  268.     * Default is 100000 (1/10 sec).  If you find it necessary to touch this,
  269.     * BE REASONABLE - and PUT BACK THE DEFAULT before you exit !!!!
  270.     * Note that Sushi itself is Signalled for all other debugging output
  271.     * any time a CR or LF is placed in buffer.  Sushi will only signal
  272.     * the external task if there is actually something in the buffer.
  273.     */
  274.    ULONG    sumicros;
  275.  
  276.    /* private stuff here - subject to moving since any additional
  277.     * public things will be added right here.
  278.     */
  279.    };
  280.  
  281.  
  282. /* Sushi's public named port - contains pointer to AppStruct above */
  283. struct WTP {
  284.    struct MsgPort wtPort;
  285.    struct AppStruct *appstruct;
  286.    /* private stuff here - subject to moving since any additional
  287.     * public things will be added right here.
  288.     */
  289.    };
  290.  
  291. struct  WTP      *wtp = NULL;
  292. struct  AppStruct *aps = NULL;
  293. LONG    sushisignum  = -1;
  294. BOOL    GotSushi     = FALSE;
  295.  
  296.  
  297. void main(int argc, char **argv)
  298.     {
  299.     struct  Task     *mytask;
  300.     UBYTE           *buf;    
  301.     ULONG   sushisignal, signals, bufi, bufli; 
  302.     BOOL    Done;
  303.  
  304.     if(((argc)&&(argc<MINARGS))||(argv[argc-1][0]=='?'))
  305.     {
  306.     printf("%s\n%s\n",Copyright,usage);
  307.     bye("",RETURN_OK);
  308.     }
  309.  
  310.     bufli = 0;        /* this application's last index into sushi buffer */
  311.     mytask = FindTask(NULL);
  312.     GotSushi = FALSE;
  313.  
  314.     Forbid();
  315.     if (wtp = FindPort(sushiname))
  316.         {
  317.     aps = wtp->appstruct;
  318.         if(! aps->extsigtask)    /* You MUST not install if someone else has */
  319.         {
  320.             if((sushisignum = AllocSignal(-1)) != -1)
  321.             {
  322.             sushisignal     = 1L << sushisignum;
  323.  
  324.             aps->extsigtask    = mytask;
  325.             aps->extsignum     = sushisignum;
  326.             aps->extsignal    = sushisignal;
  327.         buf         = aps->subuf;
  328.             GotSushi     = TRUE;
  329.             }
  330.         }
  331.         }
  332.     Permit();
  333.  
  334.     if(!GotSushi)
  335.     bye("Can't allocate sushi - not found or in use\n", RETURN_FAIL);
  336.  
  337.     Done = FALSE;
  338.  
  339.     while(!Done)
  340.         {
  341.         signals = Wait( SIGBREAKF_CTRL_C | sushisignal );
  342.  
  343.         /* Make sure you turn off your compiler's CTRL-C handling
  344.           * if you use CTRL-C as your exit signal.
  345.           */
  346.         if( signals & SIGBREAKF_CTRL_C)
  347.         {
  348.         Done = TRUE;
  349.         }
  350.  
  351.         if(signals & sushisignal)
  352.         {
  353.         /* There's some new info in the sushi buffer.
  354.          * Here we will just print it out.
  355.          * You could instead copy it elsewhere for fancy display, etc.
  356.          */
  357.         bufi = aps->subufi;    /* grab where sushi has filled to */
  358.         
  359.         if(bufi > bufli)        /* buffer has not wrapped since last */
  360.         {
  361.         Write(Output(),&buf[bufli],bufi - bufli);
  362.         }
  363.         else if(bufli > bufi)    /* buffer has wrapped since last */        
  364.         {
  365.         /* Write end of buffer info, then new info at start of buffer */
  366.         Write(Output(),&buf[bufli],aps->subufsize - bufli);
  367.         Write(Output(),buf,bufi);
  368.         }
  369.         /* Update variable that saves where YOU are up to */
  370.         bufli = bufi;
  371.         }
  372.  
  373. #if 0
  374.     /* FYI - Other things you can tell Sushi to do */
  375.  
  376.     /* Tell Sushi to write its buffer as file t:sushi.out.
  377.      * Sushi writes its buffer in chronological order -
  378.      * i.e., if the buffer has wrapped, it writes older end of buffer,
  379.      * then writes data from start of buffer to current position.
  380.      */
  381.     Signal(aps->sutask, SIGBREAKF_CTRL_F);
  382.  
  383.     /* Tell Sushi to empty (clear) its buffer (i.e. reset its indexes).
  384.      * If you do this, you should probably reset your bufli to 0.
  385.      */
  386.     Signal(aps->sutask, SIGBREAKF_CTRL_E);
  387.  
  388.     /* Tell Sushi to exit if it can.
  389.      * It can not exit if there is an aps->extsigtask.
  390.      */
  391.     Signal(aps->sutask, SIGBREAKF_CTRL_C);
  392.  
  393. #endif
  394.  
  395.         }
  396.     bye("",RETURN_OK);    /* Will do Sushi and other cleanup */
  397.     }
  398.  
  399.  
  400. void bye(UBYTE *s, int e)
  401.     {
  402.     cleanup();
  403.     exit(e);
  404.     }
  405.  
  406.  
  407. void cleanup()
  408.     {
  409.     /* Required cleanup for external sushi program before exiting ! */
  410.     if(GotSushi && (aps != NULL))
  411.     {
  412.     /* Required Sushi cleanup before you exit !!!! */
  413.     Forbid();
  414.     aps->extsignum  = 0L;
  415.     aps->extsignal  = 0L;
  416.     aps->extsigtask = NULL;
  417.     Permit();
  418.     }
  419.     if(sushisignum != -1)    FreeSignal(sushisignum);
  420.     }
  421.  
  422.  
  423.